// Copyright(c) Sonosemi Medical Ltd. Embedded Software Team.
// Author: Zhang Yisong(zhangyisong@sonosemi.com)

#pragma once
#include "active/active_event.hpp"
#include "boost/sml.hpp"
#include <string_view>
#include <cstdio>
namespace active {

namespace internal {

struct Logger {
  template <class SM, class TEvent> void log_process_event(const TEvent &e) {
    auto event_name =
        std::string_view{boost::sml::aux::get_type_name<TEvent>()};
    if constexpr (is_event_type<TEvent>::value) {
      auto name = TEvent::Name();
      printf("[%s][process_event] %s\n", boost::sml::aux::get_type_name<SM>(),
             name.data());
      return;
    }
    if (auto pos = event_name.find("initial") != std::string_view::npos) {
      printf("[%s][process_event] initial\n",
             boost::sml::aux::get_type_name<SM>());
    } else if (auto pos = event_name.find("entry") != std::string_view::npos) {
      printf("[%s][process_event] on_entry\n",
             boost::sml::aux::get_type_name<SM>());
    } else if (auto pos = event_name.find("exit") != std::string_view::npos) {
      printf("[%s][process_event] on_exit\n",
             boost::sml::aux::get_type_name<SM>());
    }
  }
  template <class SM, class TGuard, class TEvent>
  void log_guard(const TGuard &, const TEvent &, bool result) {
    printf("[%s][guard] %s %s %s\n", boost::sml::aux::get_type_name<SM>(),
           boost::sml::aux::get_type_name<TGuard>(),
           boost::sml::aux::get_type_name<TEvent>(),
           (result ? "[OK]" : "[Reject]"));
  }

  template <class SM, class TAction, class TEvent>
  void log_action(const TAction &, const TEvent &) {
    // TODO
  }

  template <class SM, class TSrcState, class TDstState>
  void log_state_change(const TSrcState &src, const TDstState &dst) {
    printf("[%s][transition] %s -> %s\n", boost::sml::aux::get_type_name<SM>(),
           src.c_str(), dst.c_str());
  }
};

} // namespace internal
} // namespace active